package com.yss.sofa.report.engine.util;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;

import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;

public final class RenderUtil {
	//----------------------------------------------------------------------------------------------
	private static class ToCNY implements TemplateMethodModelEx{
		@SuppressWarnings("rawtypes")
		public Object exec(List arguments) throws TemplateModelException {
			try {
				double v=Double.valueOf(arguments.get(0).toString());
				return StringUtil.rmbToBigString(v);
			} catch (Exception e) {
				throw new TemplateModelException("自定义函数toCNY运行时错误",e);
			}
		}
	}
	private static class To26 implements TemplateMethodModelEx{
		@SuppressWarnings("rawtypes")
		public Object exec(List arguments) throws TemplateModelException {
			try {
				int v=Integer.valueOf(arguments.get(0).toString());
				return NumberUtil.to26(v);
			} catch (Exception e) {
				throw new TemplateModelException("自定义函数to26运行时错误",e);
			}
		}
	}
	private static class Ins implements TemplateMethodModelEx{
		@SuppressWarnings("rawtypes")
		public Object exec(List arguments) throws TemplateModelException {
			try {
				String field=arguments.get(0).toString();
				String param=arguments.get(1).toString();
				String[] values=param.split(",");
				StringBuilder sb=new StringBuilder();
				for(String value:values){
					sb.append("(");
					sb.append(field);
					sb.append("=");
					sb.append("'"+value.replaceAll("'", "''")+"'");
					sb.append(")");
					sb.append(" or ");
				}
				sb.append("(1=2)");
				return "("+sb.toString()+")";
			} catch (Exception e) {
				throw new TemplateModelException("自定义函数ins运行时错误",e);
			}
		}
	}
	//----------------------------------------------------------------------------------------------
	private static final String DEFAULT_SUFFIX=".ft";
	private static final Configuration config;
	static {
		config=new Configuration();
		config.setLocale(Locale.CHINA);
		config.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
		config.setDateFormat("yyyy-MM-dd");
		config.setNumberFormat("#.##");
		config.setDefaultEncoding("UTF-8");
		
	}
	private static String generateTemplateName(){
		return UUID.randomUUID().toString();
	}
	private static void initCostomFunctions(Map<String, Object> values){
		values.put("toCNY", new ToCNY());
		values.put("to26", new To26());
		values.put("ins", new Ins());
	}
	public static String renderFile(String path,String filename, Map<String, Object> values) throws Exception {
		config.setDirectoryForTemplateLoading(new File(path));
		initCostomFunctions(values);
		StringWriter out=new StringWriter();
		try {
			Template temp;
			try {
				temp = config.getTemplate(filename+DEFAULT_SUFFIX);
			} catch (IOException e) {
				throw new Exception("FreeMarker读取规则失败，\n文件：\n"+filename+DEFAULT_SUFFIX, e);
			}
			try {
				temp.process(values, out);
			} catch (TemplateException e) {
				throw new Exception("FreeMarker运行时错误，\n文件：\n"+filename+DEFAULT_SUFFIX+"\n变量：\n"+StringUtils.join(values.keySet(), ",\n"), e);
			} catch (IOException e) {
				throw new Exception("FreeMarker输出结果失败，\n文件：\n"+filename+DEFAULT_SUFFIX, e);
			}
			out.flush();
			return out.toString();
		} finally {
			out.close();
		}
	}
	public static String renderString(String template, Map<String,Object> values) throws Exception{
		initCostomFunctions(values);
		Configuration cfg=(Configuration)config.clone();
		String name=generateTemplateName();
		StringWriter out=new StringWriter();
		try {
			StringTemplateLoader loader=new StringTemplateLoader();
			loader.putTemplate(name, template);
			cfg.setTemplateLoader(loader);
			Template temp;
			try {
				temp = cfg.getTemplate(name);
			} catch (IOException e) {
				throw new Exception("FreeMarker读取规则失败，\n规则：\n"+template, e);
			}
			try {
				temp.process(values, out);
			} catch (TemplateException e) {
				throw new Exception("FreeMarker运行时错误，\n规则：\n"+template+"\n变量：\n"+StringUtils.join(values.keySet(), ",\n"), e);
			} catch (IOException e) {
				throw new Exception("FreeMarker输出结果失败，\n规则：\n"+template, e);
			}
			out.flush();
			return out.toString();
		} finally {
			out.close();
			cfg.clearTemplateCache();
			cfg=null;
		}
	}
}
